﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Windows.Forms;

namespace tiDE.Settings
{
    public partial class GlobalSettingEditor : Form
    {
        public GlobalSettingEditor()
        {
            InitializeComponent();
            PopulateTreeView();
        }

        void PopulateTreeView()
        {
            Type globalSettings = typeof(GlobalSettings);
            foreach (FieldInfo info in globalSettings.GetFields())
            {
                string parentNode = null, childNode = null, name = info.Name;
                bool hideFromTree = false;
                foreach (object attribute in info.GetCustomAttributes(false))
                {
                    if (attribute is SettingHideFromViewAttribute)
                        hideFromTree = true;
                    if (attribute is SettingGroupAttribute)
                        parentNode = (attribute as SettingGroupAttribute).SettingGroup;
                    if (attribute is SettingSubgroupAttribute)
                        childNode = (attribute as SettingSubgroupAttribute).SettingSubgroup;
                    if (attribute is SettingNameAttribute)
                        name = (attribute as SettingNameAttribute).Name;
                }
                if (hideFromTree)
                    continue;
                if (parentNode == null || childNode == null)
                    continue;
                TreeNode node = AddSubgroupToNode(AddGroupToTree(parentNode), childNode);
                if ((node.Tag as List<FieldInfo>) == null)
                    node.Tag = new List<FieldInfo>();
                (node.Tag as List<FieldInfo>).Add(info);
            }
        }

        TreeNode AddGroupToTree(string GroupName)
        {
            foreach (TreeNode node in treeView1.Nodes)
            {
                if (node.Text == GroupName)
                    return node;
            }
            return treeView1.Nodes.Add(GroupName);
        }

        TreeNode AddSubgroupToNode(TreeNode parentNode, string Subgroup)
        {
            foreach (TreeNode node in parentNode.Nodes)
            {
                if (node.Text == Subgroup)
                    return node;
            }
            return parentNode.Nodes.Add(Subgroup);
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Parent == null)
                return;
            panel1.Controls.Clear();
            int y = 3;
            List<FieldInfo> fieldList = e.Node.Tag as List<FieldInfo>;
            foreach (FieldInfo info in fieldList)
            {
                string name = info.Name;
                string editorName = "none";
                if (info.FieldType == typeof(string))
                    editorName = "string";
                if (info.FieldType == typeof(Color))
                    editorName = "color";
                if (info.FieldType == typeof(bool))
                    editorName = "checkbox";

                foreach (Attribute attribute in info.GetCustomAttributes(false))
                {
                    if (attribute is SettingNameAttribute)
                        name = (attribute as SettingNameAttribute).Name;
                    if (attribute is SettingEditorAttribute)
                    {
                        switch ((attribute as SettingEditorAttribute).EditorType)
                        {
                            case SpecialEditorType.FileBrowse:
                                editorName = "filebrowse";
                                break;
                        }
                    }
                }

                Label nameLabel = new Label();
                nameLabel.AutoSize = true;
                nameLabel.Location = new Point(3, y);
                y += nameLabel.Height + 3;
                nameLabel.Text = name;
                panel1.Controls.Add(nameLabel);

                switch (editorName)
                {
                    case "string":
                        TextBox inputBox = new TextBox();
                        inputBox.Text = (string)info.GetValue(tiDEWindow.GlobalSettings);
                        inputBox.Location = new Point(3, y);
                        inputBox.Width = panel1.Width - 6;
                        inputBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
                        y += inputBox.Height + 3;
                        panel1.Controls.Add(inputBox);
                        break;
                    case "color":
                        Button colorButton = new Button();
                        colorButton.Text = "Choose Color";
                        colorButton.AutoSize = true;
                        colorButton.Click += new EventHandler(colorButton_Click);
                        colorButton.Location = new Point(3, y);
                        colorButton.Width = panel1.Width - 6;
                        colorButton.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
                        colorButton.Tag = info;
                        y += colorButton.Height + 3;
                        panel1.Controls.Add(colorButton);
                        break;
                    case "checkbox":
                        CheckBox checkBox = new CheckBox();
                        checkBox.Text = "Enabled";
                        checkBox.AutoSize = true;
                        checkBox.CheckStateChanged += new EventHandler(checkBox_CheckStateChanged);
                        checkBox.Location = new Point(3, y);
                        checkBox.Width = panel1.Width - 6;
                        checkBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
                        checkBox.Tag = info;
                        checkBox.Checked = (bool)info.GetValue(tiDEWindow.GlobalSettings);
                        y += checkBox.Height + 3;
                        panel1.Controls.Add(checkBox);
                        break;
                    case "filebrowse":
                        TextBox fileBox = new TextBox();
                        fileBox.Enabled = false;
                        Button button = new Button();
                        button.AutoSize = true;
                        button.Text = "Browse";
                        button.Click += new EventHandler(showBrowseDialog);
                        button.Tag = info;
                        button.Parent = fileBox;
                        fileBox.Text = (string)info.GetValue(tiDEWindow.GlobalSettings);
                        fileBox.Location = new Point(3, y);
                        fileBox.Width = panel1.Width - 9 - button.Width;
                        button.Location = fileBox.Location + new Size(fileBox.Size.Width + 3, 0);
                        button.Anchor = AnchorStyles.Right | AnchorStyles.Top;
                        fileBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
                        y += fileBox.Height + 3;
                        panel1.Controls.Add(fileBox);
                        panel1.Controls.Add(button);
                        break;
                }
            }
        }

        void checkBox_CheckStateChanged(object sender, EventArgs e)
        {
            FieldInfo info = (sender as Control).Tag as FieldInfo;
            info.SetValue(tiDEWindow.GlobalSettings, (sender as CheckBox).Checked);
        }

        void colorButton_Click(object sender, EventArgs e)
        {
            FieldInfo info = (sender as Control).Tag as FieldInfo;
            ColorDialog dialog = new ColorDialog();
            dialog.Color = (Color)info.GetValue(tiDEWindow.GlobalSettings);
            if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            info.SetValue(tiDEWindow.GlobalSettings, dialog.Color);
        }

        void showBrowseDialog(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "All Files|*.*";
            FieldInfo info = (sender as Control).Tag as FieldInfo;
            foreach (Attribute attribute in info.GetCustomAttributes(false))
            {
                if (attribute is SettingFileBrowserFilter)
                    dialog.Filter = (attribute as SettingFileBrowserFilter).Filter;
            }
            dialog.FileName = "";
            if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            info.SetValue(tiDEWindow.GlobalSettings, dialog.FileName);
            if ((sender as Control).Parent is TextBox)
                ((sender as Control).Parent as TextBox).Text = dialog.FileName;
        }
    }
}
